package io.renren.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.additional.query.impl.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.additional.update.impl.LambdaUpdateChainWrapper;
import io.renren.common.exception.RRException;
import io.renren.dao.*;
import io.renren.entity.*;
import io.renren.service.ScheduleRebaseJobService;
import io.renren.service.SysReturnGoodsService;
import io.renren.utils.Query;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.renren.common.utils.PageUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.ObjectUtils;


@Service("sysReturnGoodsService")
public class SysReturnGoodsServiceImpl extends ServiceImpl<SysReturnGoodsDao, SysReturnGoodsEntity> implements SysReturnGoodsService {

    @Autowired
    private SysReturnGoodsDao sysReturnGoodsDao;

    @Autowired
    private  SysOrderDao sysOrderDao;


    @Autowired
    private ScheduleRebaseJobService scheduleRebaseJobService;

    @Autowired
    private UserRebateFreezeDao userRebateFreezeDao;

    @Autowired
    private  MemberDao memberDao;

    @Autowired
    private ScheduleRebaseJobDao scheduleRebaseJobDao;
    @Autowired
    private SysMerchantDao sysMerchantDao;

    @Autowired
    private SysReturnGoodsOperationDao sysReturnGoodsOperationDao;

    private Logger logger = LoggerFactory.getLogger(SysReturnGoodsServiceImpl.class);

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        Object merchant_id = params.get("merchantId");
        Object status = params.get("status");
        Object initStatus = params.get("initStatus");
        Object c1 = params.get("c1");
        Object c2 = params.get("c2");
        Object returnCode = params.get("returnCode");
        if (ObjectUtils.isEmpty(merchant_id)) throw new RRException("商户id不为空", 500);
        IPage<SysReturnGoodsEntity> page = this.page(
                new Query<SysReturnGoodsEntity>().getPage(params),
                new QueryWrapper<SysReturnGoodsEntity>().eq("merchant_id", merchant_id)
                        .and(null!=status,a->a.eq("state",status))
                        .and(null!=c1&null!=c2,d->d.between("creation_time",c1,c2))
                        .and(null!=returnCode,e->e.eq("return_code",returnCode))
                        .and(null!=initStatus,b->b.eq("init_state",initStatus))
        );

        return new PageUtils(page);
    }

    /**
     * 退货、退款
     * '正常订单状态:1未支付(默认),2已支付/未发货/已成团,3已发货,4买家确认收货/冻结中,5已完成,6已取消',
     *
     * @param id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void argessRefundOrGoods(Integer id,Integer type)   {
        //type 1、退货 2、退款
        //1、判断该退货 是否已发货  (防止被页面不刷新,状态不更新)
        SysReturnGoodsEntity sysReturnGoodsEntity = sysReturnGoodsDao.selectById(id);
        if (null == sysReturnGoodsEntity) throw new RRException("该订单不存在", 500);
        //退款
        if (type==1){
            this.argessRefund(sysReturnGoodsEntity);
        }else if (type==2){
            //退货 更改状态为 同意退货
            this.agressGoods(sysReturnGoodsEntity);
        }


    }

    @Transactional(rollbackFor = Exception.class)
    void rebaseLog(SysReturnGoodsEntity sysReturnGoodsEntity) {
        Integer orderId = sysReturnGoodsEntity.getOrderId();
        String params= "{\"orderId\":"+orderId+"}";

        List<ScheduleRebaseJobEntity> list = scheduleRebaseJobService.query().eq("params", params).list();
        if (null!=list && !list.isEmpty()) {
            List<UserRebateFreezeEntity> freezeEntityList = userRebateFreezeDao.selectList(new QueryWrapper<UserRebateFreezeEntity>().eq("order_id", orderId));
            try {
                Long[] longs = list.stream().map(ScheduleRebaseJobEntity::getJobId).toArray(Long[]::new);
                scheduleRebaseJobService.deleteBatch(longs);
                //将冻结状态改为已取消  tb_user_rebate_freeze
                if (null != freezeEntityList && !freezeEntityList.isEmpty()){
                    for (UserRebateFreezeEntity userRebateFreezeEntity : freezeEntityList) {
                        //设置为已取消
                        userRebateFreezeEntity.setState(3);
                        if (userRebateFreezeDao.updateById(userRebateFreezeEntity) != 1)
                            throw new RRException("更新失败", 500);
                    }
                }

            } catch (Exception e) {
                logger.error("删除返佣定时任务异常" + new Date().getTime() + "原因" + e.getMessage());
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                throw new RRException(e.getMessage(),500);
            }
        }

    }


    /**
     * 退货单初始状态:1已付款/待发货,2已发货,3买家确认收货/已完成'
     * 退货订单状态:1申请中,2买家申请退款,3买家申请退货,4卖家同意退货,5买家待发货,6买家已发货,7卖家确认收货,8已完成,9用户取消,10卖家拒绝退款,11卖家拒绝退货',
     * @param sysReturnGoodsEntity
     */
    @Transactional(rollbackFor = Exception.class)
    void agressGoods(SysReturnGoodsEntity sysReturnGoodsEntity) {
        Integer state = sysReturnGoodsEntity.getState();
        Integer initState = sysReturnGoodsEntity.getInitState();

        if (initState<=2){
            throw new RRException("该订单还未收货",500);
        }else if (state==3){
            //修改退货订单状态为 同意退货
            try{
                sysReturnGoodsEntity.setState(4);
                if (sysReturnGoodsDao.updateById(sysReturnGoodsEntity)!=1) throw new RRException("同意退货失败",500);
                SysReturnGoodsOperationEntity sysReturnGoodsOperationEntity = new SysReturnGoodsOperationEntity();
                sysReturnGoodsOperationEntity.setReason("商户同意退货");
                sysReturnGoodsOperationEntity.setType("商户已同意退货");
                sysReturnGoodsOperationEntity.setReturnId(sysReturnGoodsEntity.getId());
                sysReturnGoodsOperationEntity.setOperationTime(new Date());
                if (sysReturnGoodsOperationDao.insert(sysReturnGoodsOperationEntity)!=1){throw new RRException("同意退货失败",500);}
            }catch (Exception e){
                logger.error("删除返佣定时任务异常"+new Date()+"原因"+e.getMessage());
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            }


        }else {
            throw new RRException("未知异常");
        }

    }



    @Transactional(rollbackFor = Exception.class)
    @Override
    public void rejectRefund(SysReturnGoodsOperationEntity sysReturnGoodsOperationEntity) {
        Integer id = sysReturnGoodsOperationEntity.getReturnId();
        SysReturnGoodsEntity sysReturnGoodsEntity = sysReturnGoodsDao.selectById(id);
        Integer initState = sysReturnGoodsEntity.getInitState();
        Integer state = sysReturnGoodsEntity.getState();
        try{
            if (state==2){
                sysReturnGoodsEntity.setState(10);
                sysReturnGoodsDao.updateById(sysReturnGoodsEntity);
            }
            //恢复订单状态
            SysOrderEntity sysOrderEntity = sysOrderDao.selectById(sysReturnGoodsEntity.getOrderId());
            sysOrderEntity.setState(initState+1);
            int update = sysOrderDao.updateById(sysOrderEntity);
            if (update!=1){
                throw new RRException("恢复订单状态失败",500);
            }
            sysReturnGoodsOperationEntity.setOperationTime(new Date());
            sysReturnGoodsOperationDao.insert(sysReturnGoodsOperationEntity);
        }
        catch (Exception e){
            //手动执行回滚
            logger.error(new Date()+"原因"+e.getMessage());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }

    }
    /**
     * 根据订单id查询定时任务ids
     *
     * @param orderId 订单id
     * @return 定时任务ids
     */
    private Long[] getScheduleIds(Integer orderId) {
        Long[] jobIds = new LambdaQueryChainWrapper<>(scheduleRebaseJobDao)
                .eq(ScheduleRebaseJobEntity::getParams, "{\"orderId\":" + orderId + "}")
                .list().stream()
                .map(ScheduleRebaseJobEntity::getJobId)
                .toArray(Long[]::new);
        return jobIds;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void rejectGoods(SysReturnGoodsOperationEntity sysReturnGoodsOperationEntity) {
        Integer id = sysReturnGoodsOperationEntity.getReturnId();
        SysReturnGoodsEntity sysReturnGoodsEntity = sysReturnGoodsDao.selectById(id);
        Integer state = sysReturnGoodsEntity.getState();
        Integer initState = sysReturnGoodsEntity.getInitState();
        try{
            if (state==3){
                sysReturnGoodsEntity.setState(11);
                sysReturnGoodsDao.updateById(sysReturnGoodsEntity);
            }
            //恢复定时任务 3买家申请退款退货
            if (state==3){
                Long[] scheduleIds = this.getScheduleIds(sysReturnGoodsEntity.getOrderId());
                if (scheduleIds.length>0){
                    scheduleRebaseJobService.resume(scheduleIds);
                }

            }
            //恢复订单状态
            SysOrderEntity sysOrderEntity = sysOrderDao.selectById(sysReturnGoodsEntity.getOrderId());
            sysOrderEntity.setState(initState+1);
            int update = sysOrderDao.updateById(sysOrderEntity);
            if (update!=1){
                throw new RRException("恢复订单状态失败",500);
            }
            sysReturnGoodsOperationEntity.setOperationTime(new Date());
            sysReturnGoodsOperationDao.insert(sysReturnGoodsOperationEntity);
        }
        catch (Exception e){
            logger.error(new Date()+"原因"+e.getMessage());
            //手动执行回滚
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
    }

    @Override
    public SysOrderEntity selectById(Integer id) {
        SysReturnGoodsEntity sysReturnGoodsEntity = sysReturnGoodsDao.selectById(id);
        if (null==sysReturnGoodsEntity)throw new RRException("订单为空",500);
        Integer orderId = sysReturnGoodsEntity.getOrderId();
        SysOrderEntity sysOrderEntity = sysOrderDao.queryDetailById(orderId);
        //查询操作列表
        if (null==sysOrderEntity)throw new RRException("相关订单不存在",500);
        List<SysReturnGoodsOperationEntity> operations = sysReturnGoodsOperationDao.selectList(new QueryWrapper<SysReturnGoodsOperationEntity>().eq("return_id", id));
        sysOrderEntity.setOperation(operations);
        sysOrderEntity.setReturnGoods(sysReturnGoodsEntity);
        return sysOrderEntity;
    }

    //确认收货
    @Transactional(rollbackFor = Exception.class)
    public void emitGoods(Integer id) {
        //查询
        SysReturnGoodsEntity sysReturnGoodsEntity = sysReturnGoodsDao.selectById(id);
        Integer merchantId = sysReturnGoodsEntity.getMerchantId();
        SysMerchantEntity sysMerchantEntity = sysMerchantDao.selectById(merchantId);
        Integer merchantState = sysMerchantEntity.getState();
        if (merchantState==2)throw new RRException("商户账号已被锁定",500);
        Integer orderId = sysReturnGoodsEntity.getOrderId();
        //查询商品列表 退货
        /**
         * 订单状态:1申请中,2买家申请退款,3买家申请退货,4卖家同意退货,5买家待发货,6买家已发货,7卖家确认收货,8已完成,9用户取消,10卖家拒绝退款,11卖家拒绝退货',
         */
        List<SysProductSkuEntity> sysProductSkuEntities = sysOrderDao.selectProductList(orderId, merchantId);
        try {
            for (SysProductSkuEntity sku:sysProductSkuEntities) {
                int i = sysOrderDao.updateStock(sku.getId(), sku.getAmount());
                if (i!=1) throw new RRException("更新库存失败",500);
            }
            //执行退款
            BigDecimal money = sysMerchantEntity.getMoney();
            BigDecimal returnMoney = sysReturnGoodsEntity.getMoney();

            if (money.compareTo(returnMoney)==-1)throw new RRException("请先充值金额在进行退款操作",500);
            //判断商户的姐是否充足
            BigDecimal subtract = money.subtract(returnMoney);
            //退货订单（插入时，正常订单初始状态 1未支付(默认),2已支付/未发货/已成团,3已发货,
            Integer state = sysReturnGoodsEntity.getState();
            if (state == 6) {
                //买家已发货 卖家等待收货
                sysMerchantEntity.setMoney(subtract);
                if (sysMerchantDao.updateById(sysMerchantEntity)!=1)throw new RRException(new Date()+"更新商户余额失败",500);
                //更新退货订单状态
                sysReturnGoodsEntity.setRefundable(2);
                sysReturnGoodsEntity.setState(8);
                if (sysReturnGoodsDao.updateById(sysReturnGoodsEntity)!=1)throw new RRException("更新退货状态失败",500);

                SysReturnGoodsOperationEntity sysReturnGoodsOperationEntity = new SysReturnGoodsOperationEntity();
                sysReturnGoodsOperationEntity.setReason("商户已确认收货");
                sysReturnGoodsOperationEntity.setType("商户已确认收货");
                sysReturnGoodsOperationEntity.setReturnId(id);
                sysReturnGoodsOperationEntity.setOperationTime(new Date());
                if (sysReturnGoodsOperationDao.insert(sysReturnGoodsOperationEntity)!=1)throw new RRException("插入失败",500);
                //取消定时任务 、返佣
                this.rebaseLog(sysReturnGoodsEntity);
            } else if (state == 7) {
                //已确认收货
                throw new RRException("该退货订单已确认收货,请刷新一下页面",500);
            }
        }catch (Exception e){
            //手动执行回滚
            logger.error(new Date()+"原因"+e.getMessage());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw new RRException(e.getMessage(),500);
        }




    }

    //立即退款
    /**
     *  * 退货订单状态:1申请中,2买家申请退款,3买家申请退货,4卖家同意退货,5买家待发货,6买家已发货,7卖家确认收货,8已完成,9用户取消,10卖家拒绝退款,11卖家拒绝退货',
     * @param sysReturnGoodsEntity
     */
    @Transactional(rollbackFor = Exception.class)
    void argessRefund(SysReturnGoodsEntity sysReturnGoodsEntity)   {
        //查询
        Integer merchantId = sysReturnGoodsEntity.getMerchantId();
        Integer userId = sysReturnGoodsEntity.getUserId();

        SysMerchantEntity sysMerchantEntity = sysMerchantDao.selectById(merchantId);
        Integer state = sysMerchantEntity.getState();
        if (state==2)throw new RRException("商户账号已被锁定",500);

        //订单id
        Integer orderId = sysReturnGoodsEntity.getOrderId();
        BigDecimal money = sysMerchantEntity.getMoney();
        BigDecimal returnMoney = sysReturnGoodsEntity.getMoney();

        //退货订单（插入时，正常订单初始状态 1未支付(默认),2已支付/未发货/已成团,3已发货,
        // refundable  1未退款
        Integer initState = sysReturnGoodsEntity.getInitState();
        Integer refundable = sysReturnGoodsEntity.getRefundable();
        if (refundable==2){
            throw new RRException("已退款",0);
        }
        if (initState == 1) {
            try{
                //未发货 未发货 执行退款
                if (money.compareTo(returnMoney)==-1)throw new RRException("商户余额不足",500);
                BigDecimal add = money.subtract(returnMoney);
                sysMerchantEntity.setMoney(add);
                if (sysMerchantDao.updateById(sysMerchantEntity)!=1)throw new RRException("更新商户余额失败",500);
                MemberEntity memberEntity = memberDao.selectById(userId);
                BigDecimal add1 = memberEntity.getBalance().add(returnMoney);

                //更新用户
                memberEntity.setBalance(add1);
                if (memberDao.updateById(memberEntity)!=1)throw new RRException("更新用户库存",500);

                //更新退货单
                sysReturnGoodsEntity.setState(8);
                sysReturnGoodsEntity.setRefundable(2);
                if (sysReturnGoodsDao.updateById(sysReturnGoodsEntity)!=1)throw new RRException("更新订单状态失败",500);

                SysReturnGoodsOperationEntity sysReturnGoodsOperationEntity = new SysReturnGoodsOperationEntity();
                sysReturnGoodsOperationEntity.setReturnId(sysReturnGoodsEntity.getId());
                sysReturnGoodsOperationEntity.setType("商户同意退款");
                sysReturnGoodsOperationEntity.setReason("");
                sysReturnGoodsOperationEntity.setOperationTime(new Date());
                sysReturnGoodsOperationDao.insert(sysReturnGoodsOperationEntity);

            }catch (Exception e){
                //手动执行回滚
                logger.error(new Date()+"原因"+e.getMessage());
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

            }

        } else if (initState == 3) {
            //已发货
            throw new RRException("该订单已发货状态，请取消后申请退款退货",500);
        }else if (initState == 2){
            throw new RRException("该订单卖家已发货，请先确认收货,500");
        }


    }
//
//    @Override
//    @Transactional
//    public void agree(Integer id, Boolean state) {
//        // 更新退货订单状态：4商家同意
//        boolean update = new LambdaUpdateChainWrapper<>(sysReturnGoodsDao)
//                .eq(SysReturnGoodsEntity::getId, id)
//                .set(SysReturnGoodsEntity::getState, 4)
//                .update();
//        if (!update) {
//            throw new RRException("退货状态更新失败", 502);
//        }
//        // 判断是否发货
//        if (!state) {
//            // 未发货
//            SysReturnGoodsEntity returnGoodsEntity = sysReturnGoodsDao.selectById(id);
//            Integer orderId = returnGoodsEntity.getOrderId();
//            // 1、商户库存增长
//            // 1.0、查询订单-商品中间表中商品和数量
//            SysOrderEntity orderEntity = sysOrderDao.queryDetailById(orderId);
//            List<SysProductEntity> products = orderEntity.getProducts();
////            // 1.1、删除订单-商品中间表中对应的记录
////            int delete = sysOrderDao.deleteByOrderId(orderId);
////            if (delete <= 0) {
////                throw new RRException("删除订单商品表失败", 503);
////            }
//            // 1.2、对应商品库存增加
//            for (SysProductEntity product : products) {
//                product.setInStock(product.getInStock() + product.getAmount());
//                boolean update1 = new LambdaUpdateChainWrapper<>(sysProductDao)
//                        .eq(SysProductEntity::getId, product.getId())
//                        .set(SysProductEntity::getInStock, product.getInStock())
//                        .update();
//                if (!update1) {
//                    throw new RRException("更新商品库存失败", 502);
//                }
//            }
//
//            // 2、支付金额有冻结表中转入用户
//            // 2.1、更新冻结记录状态: 完成
//            int i = userPaymentFreezeDao.updateSateByid(orderId);
//            if (i <= 0) {
//                throw new RRException("更新冻结表状态失败", 502);
//            }
//            // 2.2、查询冻结金额
//            BigDecimal money = userPaymentFreezeDao.queryMoneyById(orderId);
//            // 2.3、用户金额增加
//            boolean update1 = new LambdaUpdateChainWrapper<>(memberDao)
//                    .eq(MemberEntity::getUserId, orderEntity.getUserId())
//                    .set(MemberEntity::getBalance, money)
//                    .update();
//            if (!update1) {
//                throw new RRException("用户余额更新失败", 502);
//            }
//        } else {
//            // 已发货，转到客户点击发货逻辑
//        }
//
//    }
//
//    @Override
//    public PageUtils queryByRetailOrMerchantId(Integer id, int type, Map<String, Object> params) {
//        IPage<SysReturnGoodsEntity> page = new LambdaQueryChainWrapper<>(sysReturnGoodsDao)
//                .eq(type == 1, SysReturnGoodsEntity::getStoreId, id)
//                .eq(type == 2, SysReturnGoodsEntity::getMerchantId, id)
//                .eq(SysReturnGoodsEntity::getType, type)
//                .page(new Query<SysReturnGoodsEntity>().getPage(params));
//
//        return new PageUtils(page);
//    }
//
//    @Override
//    public SysReturnGoodsEntity queryDetailById(Integer id) {
//        // TODO: 2020/11/15
//        // 1、查询退货对象
//        // 2、封装门店或者商铺信息
//        // 3、封装用户信息
//        // 4、封装商品信息
//        return null;
//    }
//
//    @Override
//    @Transactional
//    public void confimReceipt(SysReturnGoodsEntity sysReturnGoodsEntity) {
//        // 1、修改订单状态
//        boolean update = new LambdaUpdateChainWrapper<>(sysReturnGoodsDao)
//                .eq(SysReturnGoodsEntity::getId, sysReturnGoodsEntity.getId())
//                .set(SysReturnGoodsEntity::getState, 7)
//                .update();
//        if (!update) {
//            throw new RRException("更新退货订单失败", 502);
//        }
//        // 2、商户库存增加
//        // 2.1、查询订单商品
//        SysOrderEntity sysOrderEntity = sysOrderDao.queryDetailById(sysReturnGoodsEntity.getOrderId());
//        List<SysProductEntity> products = sysOrderEntity.getProducts();
//        // 2.2、产品表对应库存增加
//        for (SysProductEntity productEntity : products) {
//            boolean update1 = new LambdaUpdateChainWrapper<>(sysProductDao)
//                    .eq(SysProductEntity::getId, productEntity.getId())
//                    .set(SysProductEntity::getInStock, productEntity.getInStock() + productEntity.getAmount())
//                    .update();
//            if (!update1) {
//                throw new RRException("恢复商品库存失败", 502);
//            }
//        }
//        // 3、费用返还
//        // 3.1、查询支付冻结表中用户及支付金额
//        BigDecimal money = sysReturnGoodsEntity.getMoney();
//        // 3.2、对应用户余额增加
//        MemberEntity member = sysOrderEntity.getMember();
//        boolean update1 = new LambdaUpdateChainWrapper<>(memberDao)
//                .eq(MemberEntity::getUserId, member.getUserId())
//                .set(MemberEntity::getBalance, member.getBalance().add(money))
//                .update();
//        if (!update1) {
//            throw new RRException("用户余额更新失败", 502);
//        }
//    }
//
//    @Override
//    public void returnGoods(SysReturnGoodsEntity sysReturnGoodsEntity) {
//        // TODO: 2020/11/16
//        // 1、修改订单状态
//        boolean update = new LambdaUpdateChainWrapper<>(sysReturnGoodsDao)
//                .eq(SysReturnGoodsEntity::getId, sysReturnGoodsEntity.getId())
//                .set(SysReturnGoodsEntity::getState, 5)
//                .update();
//        if (!update) {
//            throw new RRException("更新退货订单状态失败", 502);
//        }
//        // 2、发快递
//        // TODO: 2020/11/16
//        // 2.1、封装订单信息
//        // 2.2、调用快递鸟接口，发送订单
//        // 2.3、处理返回数据
//    }


}
